package org.rcy.framework.data.service;

import java.io.Serializable;
import java.util.Optional;

public interface CrudService<T,ID extends Serializable> {
	/**
	 * Insert a new entity to db by the given entity .创建指定对象</br>
	 * <strong>为Null的属性不会保存，会使用数据库默认值</strong>
	 * @return the saved entity will never be {@literal null}.
	 */
	T create(T entity);

	/**
	 * 更新指定的实体对象到数据库，<strong>对象中的null属性会被更新</strong>
	 * @param entity
	 */
	boolean update(T entity);

	/**
	 * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
	 * entity instance completely.
	 * <p>更新全部数据（包括null值）,若对象主键为空，则insert对象到数据库</p>
	 * It can be judged to update or insert by checking the id is or not null.
	 * @param entity must not be {@literal null}.
	 * @return the saved entity will never be {@literal null}.
	 */
	<S extends T> S save(S entity);

	/**
	 * Retrieves an entity by its id. 该方法由持久层框架自动实现，单表查询，未实现关联
	 *
	 * @param id must not be {@literal null}.
	 * @return the entity with the given id or {@literal Optional#empty()} if none found
	 * @throws IllegalArgumentException if {@code id} is {@literal null}.
	 */
	Optional<T> findById(ID id);

	/**
	 * Get a entity primary key. Usually it's called id.
	 *
	 * @param id primary key's value
	 * @return 带关联的实体
	 */
	T get(ID id);

	/**
	 * Returns whether an entity with the given id exists.
	 *
	 * @param id must not be {@literal null}.
	 * @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
	 * @throws IllegalArgumentException if {@code id} is {@literal null}.
	 */
	boolean existsById(ID id);

	/**
	 * 根据实体类条件查询一条记录
	 * @param t
	 * @return
	 */
	Optional<T> findOne(T t);

	/**
	 * 根据实体类条件查询集合
	 * @param t
	 * @return
	 */
	Iterable<T> query(T t);

	/**
	 * Deletes the entity with the given id.
	 *
	 * @param id must not be {@literal null}.
	 * @throws IllegalArgumentException in case the given {@code id} is {@literal null}
	 */
	boolean delete(ID id);

	/**
	 * Deletes a given entity.
	 *
	 * @param entity
	 * @throws IllegalArgumentException in case the given entity is {@literal null}.
	 */
	void delete(T entity);

}
